package com.vanke.devops.domain.domain.zuulroute.impl;


import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.google.common.collect.Lists;
import com.vanke.core.util.RestClient;
import com.vanke.devops.dal.dao.ZuulRouteMapper;
import com.vanke.devops.dal.model.ZuulRoute;
import com.vanke.devops.dal.model.table.ZuulRouteTable;
import com.vanke.devops.dal.util.collection.CollectionUtils;
import com.vanke.devops.domain.domain.zuulroute.IZuulRouteService;
import com.vanke.devops.domain.domain.zuulroute.param.ZuulRouteParam;
import com.vanke.devops.domain.enums.ZuulRouteErrorCode;
import com.vanke.devops.dto.ZuulRouteDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.vanke.devops.domain.base.BaseServiceImpl;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表  服务实现类
 * </p>
 *
 * @author 陈景阳
 * @since 2018-05-11
 */
@Service
public class ZuulRouteServiceImpl extends BaseServiceImpl<ZuulRouteMapper, ZuulRoute> implements IZuulRouteService {

    @Autowired
    private RestClient restClient;

    @Override
    public List<ZuulRouteDTO> all() {
        List<ZuulRoute> list = baseMapper.selectList(new EntityWrapper<>());
        return list.stream()
                .map(this::getZuulRouteDTO)
                .collect(Collectors.toList());
    }

    @Override
    public ZuulRouteDTO add(ZuulRouteParam param) {
        boolean existPath = this.existPath(param.getPath(),null);
        if(existPath){
            throw ZuulRouteErrorCode.PATH_EXIST.getException();
        }
        boolean existHostAndLocation = this.existHostAndLocation(param.getHost(),param.getLocation(),null);
        if(existHostAndLocation){
            throw ZuulRouteErrorCode.HOST_LOCATION_EXIST.getException();
        }
        ZuulRoute entity = this.getZuulRoute(param);
        super.add(entity);
        return getInfo(entity.getId());
    }

    private boolean existPath(String path,Integer id){
        Wrapper<ZuulRoute> wrapper = new EntityWrapper<>();
        wrapper.eq(ZuulRouteTable.path,path);
        if(id != null){
            wrapper.ne(ZuulRouteTable.id,id);
        }
        List<ZuulRoute> list = baseMapper.selectList(wrapper);
        return list.size() > 0;
    }

    private boolean existHostAndLocation(String host,String location,Integer id){
        Wrapper<ZuulRoute> wrapper = new EntityWrapper<>();
        wrapper.eq(ZuulRouteTable.host,host);
        wrapper.eq(ZuulRouteTable.location,location);
        if(id != null){
            wrapper.ne(ZuulRouteTable.id,id);
        }
        List<ZuulRoute> list = baseMapper.selectList(wrapper);
        return list.size() > 0;
    }

    @Override
    public ZuulRouteDTO getInfo(Integer id) {
        ZuulRoute entity = super.queryById(id);
        return this.getZuulRouteDTO(entity);
    }

    @Override
    public ZuulRouteDTO update(Integer id, ZuulRouteParam param) {
        boolean existPath = this.existPath(param.getPath(),id);
        if(existPath){
            throw ZuulRouteErrorCode.PATH_EXIST.getException();
        }
        boolean existHostAndLocation = this.existHostAndLocation(param.getHost(),param.getLocation(),id);
        if(existHostAndLocation){
            throw ZuulRouteErrorCode.HOST_LOCATION_EXIST.getException();
        }

        ZuulRoute entity = this.getZuulRoute(param);
        entity.setId(id);
        super.update(entity);
        return getInfo(id);
    }

    @Override
    public Page<ZuulRouteDTO> page(Integer pageNo, Integer pageSize,String keyword) {
        Page<ZuulRoute> page = new Page<>(pageNo,pageSize);
        Page<ZuulRouteDTO> resultPage = new Page<>();
        ZuulRoute entity = new ZuulRoute();
        List<String> fields = Lists.newArrayList();
        fields.add(ZuulRouteTable.host);
        fields.add(ZuulRouteTable.location);
        fields.add(ZuulRouteTable.path);
        fields.add(ZuulRouteTable.service_name);
        entity.setFields(fields);
        entity.setKeyword(keyword);
        List<ZuulRoute> list = baseMapper.selectRecords(page,entity);
        List<ZuulRouteDTO> resultList = CollectionUtils.selectListByCopy(list,ZuulRouteDTO.class);
        resultPage.setRecords(resultList);
        resultPage.setTotal(page.getTotal());
        return resultPage;
    }

    @Override
    public void publish() {
        try {
            //TODO 开发环境地址写死
            String url = "http://172.18.16.18:2222/refresh-zuul-route";
            restClient.get(url,Object.class);
        } catch (IOException e) {
            e.printStackTrace();
            throw ZuulRouteErrorCode.ZUUL_ROUTE_PUBLISH_ERROR.getException();
        }
    }

    private ZuulRoute getZuulRoute(ZuulRouteParam param){
        ZuulRoute entity = new ZuulRoute();
        entity.setHost(param.getHost());
        entity.setUrl(param.getUrl());
        entity.setContextPath(param.getContextPath());
        entity.setServiceName(param.getServiceName());
        entity.setPath(param.getPath());
        entity.setSort(param.getSort());
        entity.setLocation(param.getLocation());
        return entity;
    }

    private ZuulRouteDTO getZuulRouteDTO(ZuulRoute entity){
        ZuulRouteDTO dto = new ZuulRouteDTO();
        dto.setId(entity.getId());
        dto.setHost(entity.getHost());
        dto.setUrl(entity.getUrl());
        dto.setContextPath(entity.getContextPath());
        dto.setServiceName(entity.getServiceName());
        dto.setPath(entity.getPath());
        dto.setSort(entity.getSort());
        dto.setLocation(entity.getLocation());
        return dto;
    }
}